#pragma once
#include <type_traits>
#include <utility>
#include <stdexcept>

// Optional类: 用于表示可能包含或不包含值的容器
// T: 存储的值的类型
template<typename T>
class Optional
{
    // 使用aligned_storage来确保正确的内存对齐
    
    using data_t = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
public:
    // 默认构造函数：创建一个未初始化的Optional对象
    Optional() : has_init_(false) {}

    // 从左值构造
    Optional(const T& v)
    {
        create(v);
    }

    // 从右值构造
    Optional(T&& v) : has_init_(false)
    {
        create(std::move(v));
    }

    // 析构函数：如果存储了对象，则销毁它
    ~Optional()
    {
        destroy();
    }

    // 拷贝构造函数
    Optional(const Optional& other) : has_init_(false)
    {
        if (other.isInit())
            assign(other);
    }

    // 移动构造函数
    Optional(Optional&& other) : has_init_(false)
    {
        if (other.isInit())
        {
            assign(std::move(other));
            other.destroy();
        }
    }

    // 移动赋值运算符
    Optional& operator=(Optional &&other)
    {
        assign(std::move(other));
        return *this;
    }

    // 拷贝赋值运算符
    Optional& operator=(const Optional &other)
    {
        assign(other);
        return *this;
    }

    // 原地构造：直接在Optional内部构造对象
    template<class... Args>
    void emplace(Args&&... args)
    {
        destroy();
        create(std::forward<Args>(args)...);
    }

    // 检查是否已初始化
    bool isInit() const { return has_init_; }

    // 布尔转换运算符
    explicit operator bool() const 
    {
        return isInit();
    }

    // 解引用运算符：访问存储的值
    T& operator*()
    {
        if(isInit())
        {
            return *((T*) (&data_));
        }

        throw std::logic_error{"try to get data in a Optional which is not initialized"};
    }

    // const版本的解引用运算符
    const T& operator*() const
    {
        if(isInit())
        {
            return *((T*) (&data_));
        }

        throw std::logic_error{"try to get data in a Optional which is not initialized"};
    }

    // 箭头运算符：访问存储对象的成员
    T* operator->()
    {
        return &operator*();
    }

    // const版本的箭头运算符
    const T* operator->() const
    {
        return &operator*();
    }

    // 相等比较运算符
    bool operator==(const Optional<T>& rhs) const
    {
        return (!bool(*this)) != (!rhs) ? false : (!bool(*this) ? true : (*(*this)) == (*rhs));
    }

    // 小于比较运算符
    bool operator<(const Optional<T>& rhs) const
    {
        return !rhs ? false : (!bool(*this) ? true : (*(*this) < (*rhs)));
    }

    // 不等比较运算符
    bool operator!=(const Optional<T>& rhs)
    {
        return !(*this == (rhs));
    }

private:
    // 在存储位置构造对象
    template<class... Args>
    void create(Args&&... args)
    {
        new (&data_) T(std::forward<Args>(args)...);
        has_init_ = true;
    }

    // 销毁存储的对象
    void destroy()
    {
        if (has_init_)
        {
            has_init_ = false;
            ((T*) (&data_))->~T();
        }
    }

    // 赋值辅助函数（拷贝）
    void assign(const Optional& other)
    {
        if (other.isInit())
        {
            copy(other.data_);
            has_init_ = true;
        }
        else
        {
            destroy();
        }
    }

    // 赋值辅助函数（移动）
    void assign(Optional&& other)
    {
        if (other.isInit())
        {
            move(std::move(other.data_));
            has_init_ = true;
            other.destroy();
        }
        else
        {
            destroy();
        }
    }

    // 移动数据
    void move(data_t&& val)
    {
        destroy();
        new (&data_) T(std::move(*((T*)(&val))));
    }

    // 拷贝数据
    void copy(const data_t& val)
    {
        destroy();
        new (&data_) T(*((T*) (&val)));
    }

private:
    bool has_init_;    // 标记是否已初始化
    data_t data_;      // 存储数据的内存空间
};
